String.prototype.reverse = function() {
  var s = this.split('');
  var n = this.length;
  for (var i = n >> 1, j = (n - i); --i >= 0; ++j) {
    var c = s[i];
    s[i] = s[j];
    s[j] = c;
  }
  return s.join('');
}


// global functions.
App = {

  disableForm: function(form) {
    Form.disable(form);
    Element.show('activity-indicator');
  },

  enableForm: function(form) {
    Form.enable(form);
    Element.hide('activity-indicator');
  }

};

Ledger = {

  load: function() {
    Ledger.scrollToBottom();
    Ledger.initEntries();
  },

  initEntries: function() {
    $$('#ledger-body tr').each(function(tr) {
      Event.observe(tr, 'mouseover', function(evt) {
        tr.getElementsByClassName('edit-behavior').each(function(ee) {
          ee.style.visibility = 'visible';
        });
      });
      Event.observe(tr, 'mouseout', function(evt) {
        tr.getElementsByClassName('edit-behavior').each(function(ee) {
          ee.style.visibility = 'hidden';
        });
      });
    });
  },

  scrollToBottom: function() {
    var x = $('ledger-body');
    x.scrollTop = x.scrollHeight;
  },

  afterPayeeUpdate: function(input, selected) {
    Ledger.setValueFromFirstClass('payee-id', 'entry_payee_id', selected);
    Ledger.setValueFromFirstClass('entry-debit', 'entry_debit', selected, 0);
    Ledger.setValueFromFirstClass('entry-credit', 'entry_credit', selected, 0);
    Ledger.setCategoryId(selected);
  },

  setValueFromFirstClass: function(classToFind, elementToSet, target, fallback) {
    var firstEl = document.getElementsByClassName(classToFind, target).first();
    $(elementToSet).value = firstEl ? firstEl.innerHTML : fallback;
  },

  setCategoryId: function(selected) {
    var catId = document.getElementsByClassName('category-id', selected).first();
    if (catId) catId = catId.innerHTML;

    $A($('entry_category_id').options).each(function(e) {
      if (catId == e.value) e.selected = true;
      return;
    });
  },

  deleteEntry: function(entryId) {
    alert(entryId)
  }

};

function foo(e,f,g) {alert(g);}

Money = {

  applyBehavior: function(el) {
    var classes = el.getElementsByClassName('money-behavior');

    classes.each(function(moneyElement) {
      Event.observe(moneyElement, 'focus',  Money.setClicked);
      Event.observe(moneyElement, 'blur',   Money.clearClicked);
      Event.observe(moneyElement, 'keyup',  Money.applyFormatting);
      Event.observe(moneyElement, 'change', Money.applyFormatting);
      Event.observe(moneyElement, 'blur',   Money.applyFormatting);
    });
  },

  setClicked: function() {
    if (!this.beenClicked) this.select();
    this.beenClicked = true;
  },

  clearClicked: function() {
    this.beenClicked = false;
  },

  applyFormatting: function(e) {
    var c = e.keyCode;

    var skipCodes = [
      Event.KEY_LEFT, Event.KEY_UP,  Event.KEY_RIGHT,  Event.KEY_DOWN,
      Event.KEY_HOME, Event.KEY_END, Event.KEY_PAGEUP, Event.KEY_PAGEDOWN
    ];

    if (skipCodes.include(c)) return;

    var s = this.value.replace(/[^0-9\.]/g, '');
    s = this.value = s.reverse().replace(/(\d{3})(?=\d)(?!\d*\.)/g,'$1,').reverse();

    // keep .nn
    this.value = s.replace(/(\.\d{2})(\d*)/,'$1');
  }

};

Category = {

  applyBehavior: function(el) {
    var classes = el.getElementsByClassName('category-behavior');

    classes.each(function(categoryElement) {
      Event.observe(categoryElement, 'focus',    Category.clearBuffer);
      Event.observe(categoryElement, 'blur',     Category.clearBuffer);
      Event.observe(categoryElement, 'keypress', Category.lookup);
    });
  },

  clearBuffer: function(evt) {
    Event.element(evt).buf = [];
  },

  lookup: function(evt) {
    var x = Event.element(evt);

    var b = x.buf;
    var s = String.fromCharCode(evt.charCode);

    if (!s.match(/[\w\:]/)) {x.buf = []; return true;}

    b.push(s);

    var index = x.selectedIndex;
    var options;

    if (index > 0) {
      var a = $A(x.options);
      options = [a.slice(0, index + 1), a.slice(index + 1, a.length)].reverse().flatten();
    }
    else {
      options = $A(x.options);
    }

    options.find(function(o,i) {
      var t = o.text.sub(/[^A-Za-z0-9]+/,'');

      if (t.match(new RegExp("^" + b.join(''), 'i'))) {
        o.selected = true;
        x.selectedIndex = o.index;
        x.buf = [];
        return true;
      }
    });
  }

};

Event.observe(window, 'load', function(e) {Money.applyBehavior(Event.element(e))});
//Event.observe(window, 'load', function(e) {Category.applyBehavior(Event.element(e))});

